import React from "react";

// 导入导航栏组件
import { Toast } from 'antd-mobile';

import './index.scss';

// 导入cssModules 的样式文件
// import styles from './index.module.css';

import axios from "axios";

import { AutoSizer, List } from 'react-virtualized';

// 导入utils
import {getCurrentCity} from '../../utils';

import NavHeader from "../../components/NavHeader";

// 数据格式化的方法
// list : [{}, {}]
const formatCityData = list => {
  const cityList = {};
  // const cityIndex = [];

  // 1. 遍历list数组 获取每一个城市的首字母
  list.forEach(item => {
    const first = item.short.substr(0,1);
  // 2. 判断cityList 中是否有该分类
    if (cityList[first]) {
      // 3. 如果有，直接在该分类push数据
      // cityList[first] => [{}, {}]
      cityList[first].push(item)
    } else {
      // 4. 如果没有，就先创建一个数组，然后把当前的数据信息添加到数组中
      cityList[first] = [item]
    }
  })

  // 获取索引数据
  const cityIndex = Object.keys(cityList).sort()

  return {
    cityList,
    cityIndex
  }
}


// 列表数据源
// const list = Array(100).fill('react-virtualized');

// 渲染每一行数据的渲染函数
// 函数的返回值就是表示最终渲染在页面中的内容
// function rowRenderer({
//   key, // Unique key within array of rows
//   index, // 索引号
//   isScrolling, // 当前项是否正在滚动中
//   isVisible, // 当前项在lit中是否可见
//   style, // 注意：重点属性，一定要给每一行数据添加该样式 作用：指定每一行的位置
// }) {
//   return (
//     <div key={key} style={style}>
//       456- {list[index]} - {index}- {isScrolling + ''}
//     </div>
//   );
// }

// 索引（A,B等）的高度
const  TITLE_HEIGHT = 36

// 每个城市名称的高度
const NAME_HEIGHT = 50

// 有房源的城市
const HOUSE_CITY = ['北京', '上海', '广州', '深圳']

// 封装处理字母索引的方法
const formatCityIndex = (letter) => {
  switch (letter) {
    case '#':
      return '当前定位';
    case 'hot':
      return '热门城市';
    default:
      return letter.toUpperCase();
  }
}

export default class CityList extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      cityList: {},
      cityIndex: [],
      // 指定右侧字母索引列表高亮的索引号
      activeIndex: 0,
    }

    // 创建ref对象
    this.cityListComponent = React.createRef();
  }

  async componentDidMount() {
    await this.getCityList();

    // 调用measureAllRows 提前计算list中每一项的高度, 实现scrollToRow的精确跳转
    // 注意： 调用这个方法的时候，需要保证list组件中已经有数据了，如果list组件中的数据为空，就会导致调用方法报错
    // 解决：只要保证这个方法是在获取数据之后，调用即可
    this.cityListComponent.current.measureAllRows();
  }

  // 获取城市列表数据的方法
  async getCityList() {
    const res = await axios.get('http://localhost:8080/area/city?level=1')
    // console.log('城市列表数据：',res.data);
    const { cityList, cityIndex } = formatCityData(res.data.body);

    // 获取热门城市数据
    const hotRes = await axios.get('http://localhost:8080/area/hot');
    // console.log('热门城市数据', hotRes.data);
    cityList['hot'] = hotRes.data.body;
    cityIndex.unshift('hot');

    // 获取当前定位城市
    const curCity = await getCurrentCity();

    cityList['#'] = [curCity];
    cityIndex.unshift('#');

    // console.log('当前定位的城市', curCity);
    // console.log('cityList', cityList);
    // console.log('cityIndex', cityIndex);

    this.setState({
      cityList,
      cityIndex,
    })

  }

  changeCity({ label, value }) {
    if (HOUSE_CITY.indexOf(label) > -1) {
      // 有
      localStorage.setItem('hkzf_city', JSON.stringify({ label, value }))
      this.props.history.go(-1)
    } else {
      Toast.info('该城市暂无房源', 1,null, false)
    }
  }

  // list 每一行的数据
  rowRenderer = ({
    key, // Unique key within array of rows
    index, // 索引号
    isScrolling, // 当前项是否正在滚动中
    isVisible, // 当前项在lit中是否可见
    style, // 注意：重点属性，一定要给每一行数据添加该样式 作用：指定每一行的位置
  }) => {
    // 获取每一行的字母索引
    const { cityIndex, cityList } = this.state;
    const letter = cityIndex[index];

    // 获取指定字母索引下的城市列表数据
    // console.log(cityList[letter]);

    return (
      <div key={key} style={style} className="city">
        <div className="title">{formatCityIndex(letter)}</div>
        <div className="name">
          {
            cityList[letter].map(item => (
              <div
                className="name"
                key={item.value}
                onClick={() => {this.changeCity(item)}}
              >
                {item.label}
              </div>
            ))
          }
        </div>
      </div>
    );
  }

  // 创建动态计算每一行高度的方法
  getRowHeight = ({ index }) => {
    // 所有标题高度 + 城市数量 * 城市名称的高度
    // TITLE_HEIGHT + cityList[cityIndex[index]].length * NAME_HEIGHT
    const { cityList, cityIndex } = this.state;
    return TITLE_HEIGHT + cityList[cityIndex[index]].length * NAME_HEIGHT;
  }

  // 封装渲染右侧索引列表的方法
  renderCityIndex() {
    // 获取到cityIndex，并遍历其，实现渲染
    const { cityIndex, activeIndex } = this.state;
    return cityIndex.map((item, index) => (
      <li
        className="city-index-item"
        key={item}
        onClick={()=> {
          // console.log('当前索引号：', index);
          this.cityListComponent.current.scrollToRow(index);
        }}
      >
        <span
          className={activeIndex === index ? "index-active" : ""}
        >
          {item === 'hot' ? '热': item.toUpperCase()}
        </span>
      </li>
    ));
  }

  // 用于获取list组件中渲染行的信息
  onRowsRendered = ({startIndex}) => { 
    // console.log(startIndex);
    if(this.state.activeIndex !== startIndex) {
      this.setState({
        activeIndex: startIndex
      })
    }
  }

  render () {
    return (
      <div className="cityList">
        {/* 顶部导航栏组件 */}
        <NavHeader>城市选择</NavHeader>
        
        {/* 城市列表 */}
        <AutoSizer>
          {({height, width}) => (
            <List
              ref={this.cityListComponent}
              width={width}
              height={height}
              rowCount={this.state.cityIndex.length}
              rowHeight={this.getRowHeight}
              rowRenderer={this.rowRenderer}
              onRowsRendered={this.onRowsRendered}
              scrollToAlignment="start"
            />
          )}
        </AutoSizer>

        {/* 右侧索引列表 */}
        <ul className="city-index">
          {this.renderCityIndex()}
        </ul>
      </div>
    )
  }
}